import pygame
import random
import sys
import time

# 初始化pygame
pygame.init()

# 定义颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
GRAY = (128, 128, 128)
FONT_PATH = "C:/Windows/Fonts/simhei.ttf"
# 定义字体
font = pygame.font.Font(FONT_PATH, 30)


# 游戏难度级别
DIFFICULTIES = {
    "简单": (3, 3, 1),
    "中等": (12, 12, 20),
    "困难": (24, 24, 99)
}


# 游戏窗口大小
# WINDOW_SIZE = (800, 600)
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600

# 窗口创建函数
def create_window():
    return pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    
    # screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    # pygame.display.set_caption("扫雷")
    # return screen



# 难度函数
def choose_difficulty():
    # 调用窗口
    screen = create_window()
    pygame.display.set_caption("选择难度")
    # screen = create_window()
    clock = pygame.time.Clock()

    # 绘制按钮函数
    def draw_button(screen,text,x,y,width,height):
        # 绘制按钮
        pygame.draw.rect(screen, GRAY, (x, y, width, height))
        # 绘制文本
        text_surface = font.render(text, True, BLACK)
        text_rect = text_surface.get_rect(center=(x + width / 2, y + height / 2))
        screen.blit(text_surface, text_rect)

    # 难度选择按钮
    buttons = []
    for i, (diff, (rows, cols, mines)) in enumerate(DIFFICULTIES.items()):
        button = pygame.Rect(300 , 150 + 80 * i, 200 , 50)
        buttons.append((button, diff,rows, cols, mines))

    running = True
    while running:
        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit() 
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                # 检查点击是否在按钮上
                for button,diff,rows,cols,mines in buttons:
                    if button.collidepoint(mouse_pos):
                        print(f"选择了{diff}难度")
                        return diff, rows, cols, mines                    

        # 绘制按钮
        for button, diff, rows, cols, mines in buttons:
            draw_button(screen,diff,button.x,button.y,button.width,button.height)
            text = font.render(diff, True, WHITE)
            text_rect = text.get_rect(center=button.center)
            screen.blit(text, text_rect)
        
        #更新提示
        pygame.display.flip()
        clock.tick(30) # 控制帧率30fps

def initialize_board(rows, cols, mines):
    # 创建一个空的游戏板
    border = []
    for i in range(rows):
        row  = []
        for j in range(cols):
            row.append(0)
        border.append(row)
    
    # 生成所有可能生成雷的坐标
    all_positions = [(i, j) for i in range(rows) for j in range(cols)]

    # 随机生成地雷位置
    mine_positions = random.sample(all_positions, mines)
    
    # 在游戏板上生成地雷数字
    for i, j in mine_positions:
        border[i][j] = -1
        
        # 遍历地雷周围格子
        # max(0, i-1), min(rows, i+2) 确保不超出边界
        for x in range(max(0, i-1), min(rows, i+2)):
            for y in range(max(0, j-1), min(cols, j+2)):
                # 跳过地雷本身
                if x == i and y == j:
                    continue
                # 只对非地雷格子进行计数
                if border[x][y] != -1:
                    border[x][y] += 1

    return border,mine_positions                        


# 绘制游戏板
def draw_border(screen,border,reversed,flags,rows,cols,cell_size):
    for i in range(rows):
        for j in range(cols):
            react = pygame.Rect(j * cell_size, i * cell_size + 50, cell_size, cell_size)
            # 判断是否反转
            if reversed[i][j]:
                if border[i][j] == -1:
                    pygame.draw.rect(screen, RED, react)
                else:
                    pygame.draw.rect(screen, WHITE, react)
                    if border[i][j] > 0:
                        # 判断是否包含数字
                        text = font.render(str(border[i][j]), True, BLACK)
                        text_rect = text.get_rect(center = react.center)
                        screen.blit(text, text_rect)
            else:
                pygame.draw.rect(screen, GRAY, react)
                if flags[i][j]:
                    # 绘制旗帜 - 使用三角形和直线
                    flag_x = react.centerx
                    flag_y = react.centery
                    # 旗杆
                    pygame.draw.line(screen, BLACK, (flag_x, react.y + 5), (flag_x, react.bottom - 5), 2)
                    # 旗帜（三角形）
                    if cell_size >= 20:  # 只在单元格足够大时绘制旗帜
                        pygame.draw.polygon(screen, RED, [
                            (flag_x, flag_y + 8),
                            (flag_x, flag_y + cell_size // 3),
                            (flag_x - cell_size // 4, flag_y + cell_size // 6)
                        ])
            pygame.draw.rect(screen,BLACK,react,1)


def reveal_cells(border,reversed,flags,x,y,rows,cols):
    # 确定当前不出边界
    if not (0<= x <rows and 0<= y <cols) or reversed[x][y]:
        return
    
    # 移除旗帜（如果存在）
    # 该操作，为确保在自动翻转时，不会产生插旗格子被消除，但地雷数量没有更新的bug
    if flags[x][y]:
        flags[x][y] = False

    # 翻转操作
    reversed[x][y] = True

    # 递归调用
    if border[x][y] == 0:
        for i in range(max(0, x-1), min(rows, x+2)):
            for j in range(max(0, y-1), min(cols, y+2)):
                reveal_cells(border,reversed,flags,i,j,rows,cols)



# 游戏主函数
def main_game(rows, cols, mines):
    # 调用窗口
    screen = create_window()
    pygame.display.set_caption("扫雷")
    clock = pygame.time.Clock()

    # 计算单元格大小
    cell_size = min(WINDOW_WIDTH // cols, (WINDOW_HEIGHT - 50) // rows)

    # 基本游戏参数
    border,mine_positions = initialize_board(rows, cols, mines)
    print("board:",border)
    print("mine_positions:",mine_positions)
    # 是否翻转
    reversed = [[False for _ in range(cols)] for _ in range(rows)]
    # 是否插旗
    flags = [[False for _ in range(cols)] for _ in range(rows)]
    # 游戏状态
    game_over = False
    game_win = False
    # 游戏开始时间
    start_time = time.time() 

    while True:
        screen.fill(WHITE)
        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit() 
            # 点击事件处理，确定雷旗帜事件处理
            if not game_over:
                if event.type == pygame.MOUSEBUTTONDOWN:
                    # 获取鼠标点击的位置
                    mouse_pos = pygame.mouse.get_pos()
                    if mouse_pos[1] > 50:
                        x = (mouse_pos[1] - 50) // cell_size
                        y = mouse_pos[0] // cell_size
                        # 左键点击的清空
                        if event.button == 1 and not flags[x][y]:
                            # 如果点击到地雷
                            if border[x][y] == -1:
                                game_over = True
                                win = False
                            else:
                                reveal_cells(border,reversed,flags,x,y,rows,cols)
                        # 点击右键
                        if event.button == 3:
                            # 右键点击
                            flags[x][y] = not flags[x][y]
            else:
                # 游戏结束
                if event.type == pygame.MOUSEBUTTONDOWN:
                    return

        draw_border(screen,border,reversed,flags,rows,cols,cell_size)




        # 显示剩余雷数和时间
        elapsed_time = int(time.time() - start_time)
        remaining_mines = mines - sum(sum(row) for row in flags)
        # 显示剩余雷数和时间
        mines_text = font.render(f"剩余雷数: {remaining_mines}", True, BLACK)
        screen.blit(mines_text, (WINDOW_WIDTH - 200, 10))
        time_text = font.render(f"时间: {elapsed_time}", True, BLACK)
        screen.blit(time_text, (10, 10))


        # 检查胜利条件
        if not game_over:
            # 条件1：所有的地雷被正确标记
            conditionl = all([
                reversed[i][j] or border[i][j]
                for i in range(rows)
                for j in range(cols)
            ])
            # 条件2：所有的非地雷单元格都被正确翻转
            condition2 = all([
                reversed[i][j]
                for i in range(rows)
                for j in range(cols)
                if border[i][j] != -1
            ])

            if conditionl and condition2:
                game_win = True
                game_over = True
            
            # 其他写法
            # 检查是否所有非地雷格子都已翻开
            # correct_flags = 0
            # wrong_flags = 0
            # hidden_mines = 0
            
            # for i in range(rows):
            #     for j in range(cols):
            #         if flags[i][j]:
            #             if border[i][j] == -1:
            #                 correct_flags += 1
            #             else:
            #                 wrong_flags += 1
            #         elif border[i][j] == -1 and not reversed[i][j]:
            #             hidden_mines += 1
            
            # # 胜利条件：所有地雷都被正确标记，且没有错误标记
            # if correct_flags == mines and wrong_flags == 0 and hidden_mines == 0:
            #     game_over = True
            #     game_win = True

        if game_over:
            if game_win:
                win_text = font.render("恭喜你，你赢了！", True, GREEN)
            else:
                win_text = font.render("游戏结束，你输了！", True, RED)
            screen.blit(win_text, (WINDOW_WIDTH // 2 - 100, WINDOW_HEIGHT // 2 - 20))

        #更新提示
        pygame.display.flip()
        clock.tick(30) # 控制帧率30fps

# 主函数 游戏入口
def main():
    while True:
        diff,rows,cols,mines = choose_difficulty()
        main_game(rows,cols,mines)
    

if __name__ == "__main__":
    main()
